<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class ApiSecurity
{
    /**
     * 处理传入的请求
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // 清理请求输入数据以防止XSS攻击
        $this->cleanXssInput($request);

        // 防止SQL注入
        $this->preventSqlInjection($request);

        // 设置安全响应头
        $response = $next($request);
        $this->setSecurityHeaders($response);

        return $response;
    }

    /**
     * 清理输入数据以防止XSS攻击
     *
     * @param \Illuminate\Http\Request $request
     */
    protected function cleanXssInput(Request $request)
    {
        $input = $request->all();

        array_walk_recursive($input, function (&$value) {
            if (is_string($value)) {
                // 使用Laravel的e()助手函数来转义HTML特殊字符
                $value = e($value);

                // 移除潜在的危险HTML标签和属性
                $value = strip_tags($value);

                // 移除JavaScript事件处理器
                $value = preg_replace('/on[a-zA-Z]+\s*=/', '', $value);
            }
        });

        $request->merge($input);
    }

    /**
     * 防止SQL注入攻击
     *
     * @param \Illuminate\Http\Request $request
     */
    protected function preventSqlInjection(Request $request)
    {
        $input = $request->all();

        // 定义常见的SQL注入模式
        $sqlInjectionPatterns = [
            '/\b(ALTER|CREATE|DELETE|DROP|EXEC|INSERT|MERGE|SELECT|UPDATE|UNION|TRUNCATE)\b/i',
            '/(--|#|;)/',
            '/\bor\s+1=1\b/i',
            '/\band\s+1=1\b/i',
        ];

        array_walk_recursive($input, function (&$value) use ($sqlInjectionPatterns) {
            if (is_string($value)) {
                // 检查是否包含SQL注入模式
                foreach ($sqlInjectionPatterns as $pattern) {
                    if (preg_match($pattern, $value)) {
                        // 可以选择记录日志或直接抛出异常
                        // Log::warning('Possible SQL injection attempt', ['value' => $value]);
                        $value = ''; // 清空可能包含SQL注入的字段
                    }
                }
            }
        });

        $request->merge($input);
    }

    /**
     * 设置安全响应头
     *
     * @param \Illuminate\Http\Response $response
     */
    protected function setSecurityHeaders($response)
    {
        // 设置X-XSS-Protection头来防止XSS攻击
        $response->headers->set('X-XSS-Protection', '1; mode=block');

        // 设置X-Content-Type-Options头来防止MIME类型嗅探
        $response->headers->set('X-Content-Type-Options', 'nosniff');

        // 设置X-Frame-Options头来防止点击劫持
        $response->headers->set('X-Frame-Options', 'DENY');

        // 设置Content-Security-Policy头来控制资源加载
        $response->headers->set('Content-Security-Policy', "default-src 'self'");
    }
}